<template>
  <ux-grid
    border
    show-overflow
    ref="plxTable"
    class="ux-table"
    keep-source
    v-loading="loading"
    :data="dataSource"
    :height="tableHeight"
    :highlightCurrentRow="true"
    :edit-config="{ trigger: 'click', mode: 'cell' }"
    :header-cell-style="tableThStyle"
    :cell-style="{ textAlign: 'center' }"
    :pagination-show="isPaginationShow"
    :total="total"
    :page-size="pageSize"
    :current-page="pageNum"
    :page-sizes="pageSizes"
    @handlePageSize="handlePageSize"
    @selection-change="handleSelectionChange"
  >
    <!-- 列的checkbox项 -->
    <ux-table-column
      v-if="isShowSelection"
      type="checkbox"
      width="55"
      fixed="left"
      align="center"
    />
    <!-- 列的index项 -->
    <ux-table-column v-if="isShowSortNum" :title="'序号'" type="index" width="60" fixed="left" align="center" />
    <template v-for="column in columns">
      <!-- 一级表头 -->
      <ux-table-column
        v-if="!column.children"
        :key="column.key"
        :field="column.key"
        :title="column.title"
        :property="column.key"
        :fixed="column.fixed"
        :align="column.align || 'center'"
        :min-width="column.width || 120"
        :resizable="colResizable"
        :edit-render="column.type ? true : false"
      >
        <!-- 一级表头红星标题渲染template -->
        <template v-if="column.required" v-slot:header="{ column }">
          <span style="color: #ed4014">*</span>
          <span>{{ column.title }}</span>
        </template>
        <template v-slot="scope">
          <template v-if="column.render">
            <table-column
              :index="scope.rowIndex"
              :row="scope.row"
              :col="scope.column"
              :render="column.render"
            />
          </template>
          <template v-else-if="column.formatter">
            {{ column.formatter() }}
          </template>
          <template
            v-else-if="column.key === 'action' || column.slot === 'action'"
          >
            <el-button
              type="text"
              size="small"
              @click="handleCancelSelect(scope.row, scope.rowIndex)"
              >删除</el-button
            >
          </template>
          <template
            v-else-if="column.type &&
            column.type !== 'select' &&
            column.type !== 'salePriceSelect'"
          >
            <tool-tip
              :textContent="scope.row[scope.column.property]"
            />
          </template>
          <template
            v-else-if="column.type === 'select'">
            <tool-tip
              :selectData="{
                val: scope.row[scope.column.property],
                list: column.options,
                valueName: 'value',
                labelName: 'label'
              }"
            />
          </template>
          <template v-else-if="column.type === 'salePriceSelect'">
            <tool-tip
              :selectData="{
                val: scope.row[scope.column.property],
                list: scope.row.options,
                valueName: 'saleCityNo',
                labelName: 'saleCityName'
              }"
            />
          </template>
          <template v-else>
            {{ scope.row[scope.column.property] }}
          </template>
        </template>
        <template v-slot:edit="scope">
          <!-- input -->
          <template v-if="column.type === 'input'">
            <el-input
              v-model.trim="scope.row[scope.column.property]"
              :disabled="column.disabled"
            />
          </template>
          <!-- inputChange -->
          <template v-else-if="column.type === 'inputChange'">
            <el-input
              v-model.trim="scope.row[scope.column.property]"
              :disabled="column.disabled"
              @change="
                (val) => {
                  handleRowInputModify({
                    row: scope.row,
                    val,
                    columnName: scope.column.property,
                    index: scope.rowIndex,
                  });
                }
              "
              @input="
                (val) => {
                  handleRegularCheck({
                    row: scope.row,
                    val,
                    regular: child.regular,
                    columnName: scope.column.property,
                    index: scope.rowIndex,
                  });
                }
              "
            />
          </template>
          <!-- inputNum -->
          <template v-else-if="column.type === 'inputNum'">
            <input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :min="column.minVal || 0"
              :max="column.maxVal || 99999999"
              :disabled="column.disabled"
            />
          </template>
          <!-- inputNumPrecision -->
          <template v-else-if="column.type === 'inputNumPrecision'">
            <el-input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :min="column.minVal || 0"
              :max="column.maxVal || 99999999"
              :precision="column.precision || 0"
              :disabled="column.disabled"
            />
          </template>
          <!-- inputNumChange -->
          <template v-else-if="column.type === 'inputNumChange'">
            <input-number
              v-model="scope.row[scope.column.property]"
              controls-position="right"
              :min="column.minVal || 0"
              :max="99999999"
              :disabled="column.disabled"
              @change="
                handleChangeInputNumber({
                  row: scope.row,
                  index: scope.rowIndex,
                  columnName: scope.column.property,
                })
              "
            />
          </template>
          <!-- select -->
          <template v-else-if="column.type === 'select'">
            <el-select
              :disabled="column.disabled || (column.isDisabled && column.isDisabled(scope.row))"
              v-model="scope.row[scope.column.property]"
              placeholder="请选择"
            >
              <el-option
                v-for="item in column.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
          </template>
          <!-- selectSpecial -->
          <template v-else-if="column.type === 'selectSpecial'">
            <el-select
              :disabled="column.disabled"
              v-model="scope.row[scope.column.property]"
              placeholder="请选择"
            >
              <el-option
                v-for="item in scope.row[column.options]"
                :key="item.optionValue"
                :label="item.optionHtml"
                :value="item.optionValue"
              >
              </el-option>
            </el-select>
          </template>
          <!-- salePriceSelect -->
          <template v-else-if="column.type === 'salePriceSelect'">
            <el-select
              v-model="scope.row[scope.column.property]"
              :disabled="column.disabled"
              placeholder="请选择"
              @change="val => { handleChangeSalePriceSelect({ val, row: scope.row, index: scope.rowIndex, columnName: scope.column.property }) }"
            >
              <el-option
                v-for="(item, index) in scope.row.options"
                :key="item.saleCityNo + index"
                :label="item.saleCityName"
                :value="item.saleCityNo">
              </el-option>
            </el-select>
          </template>
        </template>
      </ux-table-column>
      <!-- 二级表头 -->
      <ux-table-column v-else :key="column.title" :title="column.title">
        <!-- 一级表头红星标题渲染template -->
        <template v-if="column.required" v-slot:header="{ column }">
          <span style="color: #ed4014">*</span><span>{{ column.title }}</span>
        </template>
        <template v-for="child in column.children">
          <ux-table-column
            v-if="!child.children"
            :key="child.key"
            :field="child.key"
            :title="child.title"
            :property="child.key"
            :fixed="child.fixed"
            :resizable="colResizable"
            :align="child.align || 'center'"
            :min-width="child.width || 120"
            :edit-render="child.type ? {autofocus: '.el-input__inner'} : false"
          >
            <!-- 二级表头红星标题渲染template -->
            <template v-if="child.required" v-slot:header="{ child }">
              <span style="color: #ed4014">*</span>
              <span>{{ child.title }}</span>
            </template>
            <template v-slot="scope">
              <template v-if="child.render">
                <table-column
                  :index="scope.rowIndex"
                  :row="scope.row"
                  :col="scope.column"
                  :render="child.render"
                />
              </template>
              <template v-else-if="child.formatter">
                {{ column.formatter() }}
              </template>
              <template v-else-if="child.type && child.type !== 'select'">
                <tool-tip
                  :textContent="scope.row[scope.column.property]"
                />
              </template>
              <template
                v-else-if="child.type === 'select' || child.slot === 'selectText'">
                <tool-tip
                  :selectData="{
                    val: scope.row[scope.column.property],
                    list: child.options,
                    valueName: 'value',
                    labelName: 'label'
                  }"
                />
              </template>
              <template v-else>
                {{ scope.row[scope.column.property] }}
              </template>
            </template>
            <template v-slot:edit="scope">
              <!-- input -->
              <template v-if="child.type === 'input'">
                <el-input
                  v-model.trim="scope.row[scope.column.property]"
                  :disabled="child.disabled"
                />
              </template>
              <!-- inputChange -->
              <template v-else-if="child.type === 'inputChange'">
                <el-input
                  v-model.trim="scope.row[scope.column.property]"
                  :disabled="child.disabled"
                  @change="
                    (val) => {
                      handleRowInputModify({
                        row: scope.row,
                        val,
                        columnName: scope.column.property,
                        index: scope.rowIndex,
                      });
                    }
                  "
                  @input="
                    (val) => {
                      handleRegularCheck({
                        row: scope.row,
                        val,
                        regular: child.regular,
                        columnName: scope.column.property,
                        index: scope.rowIndex,
                      });
                    }
                  "
                />
              </template>
              <!-- inputNum -->
              <template v-else-if="child.type === 'inputNum'">
                <input-number
                  v-model="scope.row[scope.column.property]"
                  controls-position="right"
                  :min="child.minVal || 0"
                  :max="child.maxVal || 99999999"
                  :disabled="child.disabled"
                />
              </template>
              <!-- inputNumPrecision -->
              <template v-else-if="child.type === 'inputNumPrecision'">
                <input-number
                  v-model="scope.row[scope.column.property]"
                  controls-position="right"
                  :min="child.minVal || 0"
                  :max="child.maxVal || 99999999"
                  :precision="child.precision || 0"
                  :disabled="child.disabled"
                />
              </template>
              <!-- inputNumChange -->
              <template v-else-if="child.type === 'inputNumChange'">
                <input-number
                  v-model="scope.row[scope.column.property]"
                  controls-position="right"
                  :min="column.minVal || 0"
                  :max="99999999"
                  :disabled="child.disabled"
                  @change="
                    handleChangeInputNumber({
                      row: scope.row,
                      index: scope.rowIndex,
                      columnName: scope.column.property,
                    })
                  "
                />
              </template>
              <!-- select -->
              <template v-else-if="child.type === 'select'">
                <el-select
                  :disabled="child.disabled || (child.isDisabled && child.isDisabled(scope.row))"
                  v-model="scope.row[scope.column.property]"
                  placeholder="请选择"
                >
                  <el-option
                    v-for="item in child.options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </template>
              <!-- selectSpecial -->
              <template v-else-if="child.type === 'selectSpecial'">
                <el-select
                  :disabled="child.disabled"
                  v-model="scope.row[scope.column.property]"
                  placeholder="请选择"
                >
                  <el-option
                    v-for="item in scope.row[column.options]"
                    :key="item.optionValue"
                    :label="item.optionHtml"
                    :value="item.optionValue"
                  >
                  </el-option>
                </el-select>
              </template>
            </template>
          </ux-table-column>
          <!-- 三级表头 -->
          <ux-table-column v-else :key="child.title" :title="child.title">
            <!-- 二级表头红星标题渲染template -->
            <template v-if="child.required" slot="header">
              <span style="color: #ed4014">*</span
              ><span>{{ child.title }}</span>
            </template>
            <template v-for="grandson in child.children">
              <ux-table-column
                v-if="!grandson.children"
                :key="grandson.key"
                :field="grandson.key"
                :title="grandson.title"
                :fixed="grandson.fixed"
                :property="grandson.key"
                :resizable="colResizable"
                :align="grandson.align || 'center'"
                :min-width="grandson.width || 120"
                :edit-render="grandson.type ? true : false"
              >
                <template v-slot="scope">
                  <template v-if="grandson.render">
                    <table-column
                      :index="scope.rowIndex"
                      :row="scope.row"
                      :col="scope.column"
                      :render="grandson.render"
                    />
                  </template>
                  <template v-else-if="grandson.formatter">
                    {{ column.formatter() }}
                  </template>
                  <template v-else-if="grandson.type && grandson.type !== 'select'">
                    <tool-tip
                      :textContent="scope.row[scope.column.property]"
                    />
                  </template>
                  <template
                    v-else-if="grandson.type === 'select' || grandson.slot === 'selectText'">
                    <tool-tip
                      :selectData="{
                        val: scope.row[scope.column.property],
                        list: grandson.options,
                        valueName: 'value',
                        labelName: 'label'
                      }"
                    />
                  </template>
                  <template v-else>
                    {{ scope.row[scope.column.property] }}
                  </template>
                </template>
                <template v-slot:edit="scope">
                  <!-- input -->
                  <template v-if="grandson.type === 'input'">
                    <el-input
                      v-model.trim="scope.row[scope.column.property]"
                      :disabled="grandson.disabled"
                    />
                  </template>
                  <!-- inputChange -->
                  <template v-else-if="grandson.type === 'inputChange'">
                    <el-input
                      v-model.trim="scope.row[scope.column.property]"
                      :disabled="grandson.disabled"
                      @change="
                        (val) => {
                          handleRowInputModify({
                            row: scope.row,
                            val,
                            columnName: scope.column.property,
                            index: scope.rowIndex,
                          });
                        }
                      "
                      @input="
                        (val) => {
                          handleRegularCheck({
                            row: scope.row,
                            val,
                            regular: grandson.regular,
                            columnName: scope.column.property,
                            index: scope.rowIndex,
                          });
                        }
                      "
                    />
                  </template>
                  <!-- inputNum -->
                  <template v-else-if="grandson.type === 'inputNum'">
                    <input-number
                      v-model="scope.row[scope.column.property]"
                      controls-position="right"
                      :min="grandson.minVal || 0"
                      :max="grandson.maxVal || 99999999"
                      :disabled="grandson.disabled"
                    />
                  </template>
                  <!-- inputNumPrecision -->
                  <template v-else-if="grandson.type === 'inputNumPrecision'">
                    <input-number
                      v-model="scope.row[scope.column.property]"
                      controls-position="right"
                      :min="grandson.minVal || 0"
                      :max="grandson.maxVal || 99999999"
                      :precision="grandson.precision || 0"
                      :disabled="grandson.disabled"
                    />
                  </template>
                  <!-- inputNumChange -->
                  <template v-else-if="grandson.type === 'inputNumChange'">
                    <input-number
                      v-model="scope.row[scope.column.property]"
                      controls-position="right"
                      :min="column.minVal || 0"
                      :max="99999999"
                      :disabled="grandson.disabled"
                      @change="
                        handleChangeInputNumber({
                          row: scope.row,
                          index: scope.rowIndex,
                          columnName: scope.column.property,
                        })
                      "
                    />
                  </template>
                  <!-- select -->
                  <template v-else-if="grandson.type === 'select'">
                    <el-select
                      :disabled="grandson.disabled"
                      v-model="scope.row[scope.column.property]"
                      placeholder="请选择"
                    >
                      <el-option
                        v-for="item in grandson.options"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                  </template>
                  <!-- selectSpecial -->
                  <template v-else-if="grandson.type === 'selectSpecial'">
                    <el-select
                      :disabled="grandson.disabled"
                      v-model="scope.row[scope.column.property]"
                      placeholder="请选择"
                    >
                      <el-option
                        v-for="item in scope.row[column.options]"
                        :key="item.optionValue"
                        :label="item.optionHtml"
                        :value="item.optionValue"
                      >
                      </el-option>
                    </el-select>
                  </template>
                </template>
              </ux-table-column>
            </template>
          </ux-table-column>
        </template>
      </ux-table-column>
    </template>
    <ux-table-column
      align="center"
      v-if="showActionCol"
      :fixed="actionColFixed"
      :min-width="actionColWidth"
      :title="actionColLabel"
    >
      <template slot-scope="scope">
        <table-column
          :index="scope.rowIndex"
          :row="scope.row"
          :col="scope.column"
          :render="actionRender"
        />
      </template>
    </ux-table-column>
  </ux-grid>
</template>
<script>
import ToolTip from './toolTip'
import TableColumn from './tableColumn';
import InputNumber from '@/components/inputNumber/inputNumber';
/**
 * 表格type对应的组件方法
 * @input 默认input输入框，可以输入任意字符，空格除外
 * @inputChange 带有change事件方法的input输入框
 * @inputNum input数值输入框，只可以输入数字，可以设置最小值，默认最小值为0
 * @inputNumChange 带有change事件方法的inputNum输入框
 * @select 默认select下拉框，options的值和文本内容默认为’value‘和’label‘
 * @selectSpecial 特殊值名称和文本内容名称的select下拉框，options的值和文本内容默认为’optionValue‘和’optionHtml‘
*/
export default {
  components: {
    ToolTip,
    TableColumn, // render渲染的column组件
    InputNumber, // 数值输入框组件
  },
  props: {
    /* 表格column */
    columns: {
      type: Array,
      default () {
        return [];
      }
    },
    /* 表格数据源 */
    dataSource: {
      type: Array,
      default () {
        return [];
      }
    },
    /* 表格加载loading */
    loading: {
      type: Boolean,
      default: false
    },
    /* 表格是否允许拖动列宽调整大小，默认可以 */
    colResizable: {
      type: Boolean,
      default: true
    },
    /* action列固定位置，默认为右固定 */
    actionColFixed: {
      type: [Boolean, String],
      default: 'right'
    },
    /* 是否展示render渲染的action列 */
    showActionCol: {
      type: Boolean,
      default: false
    },
    /* render渲染action列的列宽，默认100 */
    actionColWidth: {
      type: Number,
      default: 100
    },
    /* render渲染action列的title，默认为’操作‘ */
    actionColLabel: {
      type: String,
      default: '操作'
    },
    /* 渲染action列的render方法 */
    actionRender: {
      type: Function,
      default: () => {}
    },
    /* 表格预定高度，默认为600 */
    tableHeight: {
      type: Number,
      default: 500
    },
    /* 表头样式 */
    tableThStyle: {
      type: Object,
      default () {
        return {
          padding: '6px 0px',
          textAlign: 'center',
          backgroundColor: '#ffffff'
        }
      }
    },
    /* 是否需要表格勾选 */
    isShowSelection: {
      type: Boolean,
      default: false
    },
    /* 是否需要表格序号 */
    isShowSortNum: {
      type: Boolean,
      default: false
    },
    /* 是否需要分页 */
    isPaginationShow: {
      type: Boolean,
      default: false
    },
    /* 分页数据 */
    total: { // 总页码
      type: Number,
      default: 0
    },
    pageSize: { // 当前每页条数
      type: Number,
      default: 10
    },
    pageNum: { // 当前页码
      type: Number,
      default: 1
    },
    pageSizes: {
      type: Array,
      default () {
        return [
          100, 500, 1000
        ]
      }
    }
  },
  methods: {
    /* 正则校验方法，输入不符合条件的内容给设成空串 */
    handleRegularCheck (data) {
      let { row, val, regular, columnName } = data;
      if (!regular) {
        return;
      }
      let replaceVal = _.replace(val, regular, '');
      row[columnName] = replaceVal;
    },
    /* inputChange的change事件方法 */
    handleRowInputModify (data) {
      this.$emit('handleRowInputModify', data);
    },
    /* inputNumChange的change事件方法 */
    handleChangeInputNumber (data) {
      this.$emit('handleChangeInputNumber', data);
    },
    /* action列的change事件方法，默认用于删除当前行 */
    handleCancelSelect (row, index) {
      this.$emit('handleCancelSelect', { row, index });
    },
    /* 表格勾选事件 */
    handleSelectionChange (rowList) {
      console.log(rowList)
      this.$emit('handleSelectionChange', rowList)
    },
    handlePageSize (data) {
      let { size, page } = data;
      if (this.pageSize !== size) {
        page = 1;
      }
      this.$emit('pagenationStateChange', { size, page });
    },
    handleChangeSalePriceSelect (data) {
      this.$emit('handleChangeSelect', data)
    },
  }
};
</script>
<style lang="less" scoped>
.ux-table {
  margin: 10px 0;
}
/* 调整单元格的字体大小 */
/deep/ .elx-cell {
  font-size: 12px;
}
/* 调整当聚焦前行高亮的背景色 */
/deep/ .row--current {
  background-color: #eaf3fe !important;
}
/deep/ .el-input__inner {
  text-align: center;
}
</style>
